#include <iostream>
#include <string.h>

using std::cout;
using std::endl;

int arr[10]={1,3,5,7,9};
//arr.operator[](idx);

//operator[](size_t idx);

class CharArray{
public:
    CharArray(size_t sz=10)
    : _size(sz)
    , _data(new char[_size])
    {
        
    }

    //重载下标访问运算符的好处：
    //1、比C语言数组的下标要安全
    //2、类类型可以重载
    //3、参数可以是任意类型，不一定是int
    
    //什么时候需要&？
    //1、流对象没有拷贝构造函数，传参以及返回都加上引用&
    //2、实体的生命周期 > 函数的生命周期
    //3、函数的参数是类类型，可以设为&，减少拷贝构造函数的使用
    char &operator[](size_t idx){   
        //这里如果不加&，则如果外面有arr[0]=‘h’，这时返回的是一个右值（临时对象）
        //右值是不能进行赋值的
        if(idx < _size){
            return _data[idx];
        }
        else
            cout<<"越界"<<endl;
            //return '\0'; \0是右值，引用不能指向右值
            static char nullchar='\0';
            return nullchar; //延长生命周期，不然局部变量不能返回引用
    }

    size_t size() const{
        return _size;
    }

    ~CharArray(){
        cout<<"析构函数"<<endl;
        if(_data){
            delete []_data;
            _data=nullptr;
        }
    }

private:
    size_t _size;
    char *_data;
};

void test(){
    const char *pstr="helloworld";
    //在C++中，字符串常量是不可修改的，
    //因此使用char*指针指向字符串常量时，应该确保不会通过该指针来修改字符串的内容
    
    CharArray ca(strlen(pstr)+1);   //  加1是为了解决\0
    for(size_t idx=0;idx!=ca.size();++idx){
        ca[idx]=pstr[idx];
    }

    for(size_t idx=0;idx!=ca.size();++idx){
        cout<<ca[idx]<<" ";
    }
    cout<<endl;
}

int main()
{   
    test();
    return 0;
}

